#include "TileManager.h"

//#include <cassert>

#include "Layer.h"
#include "Tile.h"
#include "InteractivityLayer.h"
#include "tinyxml.h"


TileManager * TileManager::s_pInstance = nullptr;

//Singleton
	TileManager* TileManager::GetInstance( void )
	{
		if( s_pInstance == nullptr )
			s_pInstance = new TileManager;

		return s_pInstance;
	}

	void	TileManager::DeleteInstance( void )
	{
		if(s_pInstance)
			delete s_pInstance;
		s_pInstance = nullptr;
	}

//Constructor
TileManager::TileManager(void)
{
	m_bIterating = false;
}

//Destructor
TileManager::~TileManager(void)
{
}
	//Tile Managment
void TileManager::AddLayer( Layer* pLayer )
{

}

void TileManager::RemoveLayer( Layer* pLayer )
{

}

	bool TileManager::LoadMap( const char * pFilePath )

	{
		// Create a TinyXML Document
	TiXmlDocument doc;


	// Attempt to load
	if( doc.LoadFile( pFilePath ) == false )
		return false;



	// Access the root node
	TiXmlElement* pRoot = doc.RootElement();	// "Map"
	if( pRoot == nullptr )
		return false;



	// Clear out the current map
	Unload();


	// Iterate through the children nodes		"Name"
	TiXmlElement* pName = pRoot->FirstChildElement( "Name" );

	//Sibling to "Name" is "Background", it's a layer.
	TiXmlElement* pBackground = pName->NextSiblingElement( "Background" );
	
	//Create a background layer to hold the background tiles
	Layer * Background = new Layer;

	//Store the Filepath for the source image for that particular layer
	{
		int h, w;
		const char * p;
		pBackground->Attribute("Height", &h);
		pBackground->Attribute("Width", &w);

		Background->SetLayerHeight(h);
		Background->SetLayerWidth(w);

		//txt
		p = pBackground->FirstChildElement("ImageFilePath")->GetText();
		
		Background->SetFilePath( p );

	}

	//Next, load in the tiles to the layer	
	TiXmlElement * pTilesList = pBackground->FirstChildElement("ImageFilePath")->NextSiblingElement("Tiles");
	TiXmlElement * pTile = pTilesList->FirstChildElement("Tile");

	while (pTile != nullptr)
	{
		//Create a new tile in which to store info you're about to retrieve
		Tile * pNewTile = new Tile;

		//Get the next tile in the list, and add it to the back.
		//Tiles will be rendered from top left to bottom right so 
		//	tile 0 will be in the top right corner.
		
		pTile->Attribute( "ID", &pNewTile->TileID);

		//Push this tile's information to the back of the tile manager.
		Background->AddTile( pNewTile );

		//Go to the next tile
		//If there's no more tiles, pTile will be null and the loop will end
		pTile = pTile->NextSiblingElement("Tile");
	}

	//The layer we just worked so hard to create must be added to the Tilemanager
	AddLayer( Background );

	//Next comes the interactivity layer.
	TiXmlElement * pInteractivity = pBackground->NextSiblingElement("Interactivity");

	//Fill in the interactivity Layer's base location
	TiXmlElement * pBase = pInteractivity->FirstChildElement("Base");
	pBase->Attribute( "x", &m_InteractiveLayer->m_Base.x);
	pBase->Attribute( "y", &m_InteractiveLayer->m_Base.y);

	 //Fill in all the spawn point data

	TiXmlElement * pSpawnPoint = pBase->NextSiblingElement("SpawnPoints")->FirstChildElement("SpawnPoint");

	while( pSpawnPoint != nullptr )
	{
		//Create a new spawn point to hold the data;
		InteractivityLayer::SpawnPoint * newSpawn = new InteractivityLayer::SpawnPoint;

		//Gather the data from the xml file
		pSpawnPoint->Attribute( "Index", &newSpawn->index );
		pSpawnPoint->Attribute("x", &newSpawn->x);
		pSpawnPoint->Attribute("y", &newSpawn->y);


		TiXmlElement * pWaypoint = pSpawnPoint->FirstChildElement("Waypoint");

		//Load in the waypoints for the spawn point above
		while ( pWaypoint != nullptr)
		{

			//Create a new Waypoint to hold the data
			InteractivityLayer::Waypoint * newWayPt = new InteractivityLayer::Waypoint;

			//Gather the data from the xml file
			pWaypoint->Attribute("Index", &newWayPt->index );
			pWaypoint->Attribute("X", &newWayPt->x);
			pWaypoint->Attribute("Y", &newWayPt->y);

			//Push the waypoint into the list
			newSpawn->Waypoints.push_back( newWayPt );

			//Go to the next waypoint
			pWaypoint = pWaypoint->NextSiblingElement("Waypoint");
		}

		//Push the spawn point onto the list
		m_InteractiveLayer->m_SpawnPoints.push_back( newSpawn );

		//Go to the next spawn point.
		pSpawnPoint = pSpawnPoint->NextSiblingElement("SpawnPoint");
	}

	//Next we'll load in the waves.
	TiXmlElement * pWave = pSpawnPoint->NextSiblingElement("Waves")->FirstChildElement("Wave");

	while (pWave != nullptr)
	{
		//Create a new wave to hold the data
		InteractivityLayer::Wave * newWave = new InteractivityLayer::Wave;


		//Gather the attribute data from the xml file
		pWave->Attribute( "Index", &newWave->index);
		pWave->Attribute( "Duration", &newWave->duration);

		//Gater the container data from the xml file
		TiXmlElement * pSpawn = pWave->FirstChildElement("Spawn");
		while (pSpawn != nullptr )
		{
			//Create a new spawn to hold the data
			InteractivityLayer::Spawn * newSpawn = new InteractivityLayer::Spawn;

			//Gather the attribute data from the xml file
			pSpawn->Attribute( "EnemyType", &newSpawn->enemyType);
			pSpawn->Attribute( "Quantity", &newSpawn->quantity);
			pSpawn->Attribute( "Duration", &newSpawn->duration);
			pSpawn->Attribute( "Delay", &newSpawn->delay);
			pSpawn->Attribute( "SpawnIndex", &newSpawn->spawnIndex);	

			//Gater the container data from the xml file
			// (no container data)

			//Push the spawn into the spawn list
			newWave->SpawnList.push_back(newSpawn);

			//Go to the next spawn
			pSpawn = pSpawn->NextSiblingElement("Spawn");
			

			
		}

		//Push the wave into the wave list
		m_InteractiveLayer->m_Waves.push_back(newWave);

		//Go to the next wave
		pWave = pWave->NextSiblingElement("Wave");
	}
	

	return false;
	}
	
	bool TileManager::LoadSaveFile( char * pFilePath )
	{
		return false;
	}

	void TileManager::Unload( void )
	{

	}

	void TileManager::Update( float fElapsedTime)
	{

	}

	void TileManager::Render( void )
	{
	}

	